import 'dart:async';

import 'package:flutter/services.dart';

import 'cloud_push_message.dart';
import 'common_callback_result.dart';

///
/// [author]: liMing
/// [Date]: 2021-09-26  19:29
///
class FlutterAliYun {
  void init() {
    print('----------->init 初始化');
    final MethodChannel _channel = const MethodChannel('com.aliYun_push')
      ..setMethodCallHandler(_handler);
  }

  ///注意可能被多次调用。
  ///Android SDK文档原话如下：
  ///如果设备成功注册，将回调callback.onSuccess()方法。
  ///但如果注册服务器连接失败，则调用callback.onFailed方法，并且自动进行重新注册，直到onSuccess为止。（重试规则会由网络切换等时间自动触发。）
  ///请在网络通畅的情况下进行相关的初始化调试，如果网络不通，或者App信息配置错误，在onFailed方法中，会有相应的错误码返回，可参考错误处理
  StreamController<CommonCallbackResult>_initCloudChannelResultController = StreamController.broadcast();

  Stream<CommonCallbackResult> get initCloudChannelResult =>
      _initCloudChannelResultController.stream;

  ///1.onNotificationRemoved 删除通知时回调该方法，通知删除上报由SDK自动完成。
  StreamController<String> _onNotificationRemovedController =
      StreamController.broadcast();

  Stream<String> get onNotificationRemoved =>
      _onNotificationRemovedController.stream;

  ///2.onNotification 客户端接收到通知后，回调该方法。
  ///可获取到并处理通知相关的参数。
  StreamController<OnNotification> _onNotificationController =
      StreamController.broadcast();

  Stream<OnNotification> get onNotification => _onNotificationController.stream;

  ///3.onMessage 用于接收服务端推送的消息。
  ///消息不会弹窗，而是回调该方法。
  StreamController<CloudPushMessage> _onMessageArrivedController =
      StreamController.broadcast();

  Stream<CloudPushMessage> get onMessageArrived =>
      _onMessageArrivedController.stream;

  ///4.onNotificationOpened 打开通知时会回调该方法，通知打开上报由SDK自动完成。
  StreamController<OnNotificationOpened> _onNotificationOpenedController =
      StreamController.broadcast();

  Stream<OnNotificationOpened> get onNotificationOpened =>
      _onNotificationOpenedController.stream;

  ///5.onNotificationReceivedInApp 当用户创建自定义通知样式，并且设置推送应用内到达不创建通知弹窗时调用该回调，且此时不调用onNotification回调(v2.3.3及以上版本支持)
  StreamController<OnNotificationReceivedInApp>
      _onNotificationReceivedInAppController = StreamController.broadcast();

  Stream<OnNotificationReceivedInApp> get onNotificationReceivedInApp =>
      _onNotificationReceivedInAppController.stream;

  ///6.onNotificationClickedWithNoAction 打开无跳转逻辑(open=4)通知时回调该方法(v2.3.2及以上版本支持)，通知打开上报由SDK自动完成。
  StreamController<OnNotificationClickedWithNoAction>
      _onNotificationClickedWithNoActionController =
      StreamController.broadcast();

  Stream<OnNotificationClickedWithNoAction>
      get onNotificationClickedWithNoAction =>
          _onNotificationClickedWithNoActionController.stream;

  Future<dynamic> _handler(MethodCall methodCall) {
    switch (methodCall.method) {
      case 'initCloudChannelResult':
        _initCloudChannelResultController.add(CommonCallbackResult(
          isSuccessful: methodCall.arguments["isSuccessful"],
          response: methodCall.arguments["response"],
          errorCode: methodCall.arguments["errorCode"],
          errorMessage: methodCall.arguments["errorMessage"],
        ));
        print("----------->init initCloudChannelResult");
        break;
      case 'onMessageArrived':
        _onMessageArrivedController.add(CloudPushMessage(
            messageId: methodCall.arguments['messageId'],
            appId: methodCall.arguments['appId'],
            title: methodCall.arguments['title'],
            content: methodCall.arguments['content'],
            traceInfo: methodCall.arguments['traceInfo']));
        break;
      case 'onNotification':
        _onNotificationController.add(OnNotification(
            methodCall.arguments['title'],
            methodCall.arguments['summary'],
            methodCall.arguments['extras']));
        break;
      case 'onNotificationOpened':
        _onNotificationOpenedController.add(OnNotificationOpened(
            methodCall.arguments["title"],
            methodCall.arguments["summary"],
            methodCall.arguments["extras"],
            methodCall.arguments["subtitle"],
            methodCall.arguments["badge"]));
        break;
      case 'onNotificationRemoved':
        _onNotificationRemovedController.add(methodCall.arguments);
        break;
      case 'onNotificationClickedWithNoAction':
        _onNotificationClickedWithNoActionController.add(
            OnNotificationClickedWithNoAction(
                methodCall.arguments["title"],
                methodCall.arguments["summary"],
                methodCall.arguments["extras"]));
        break;
      case 'onNotificationReceivedInApp':
        _onNotificationReceivedInAppController.add(OnNotificationReceivedInApp(
            methodCall.arguments["title"],
            methodCall.arguments["summary"],
            methodCall.arguments["extras"],
            methodCall.arguments["openType"],
            methodCall.arguments["openActivity"],
            methodCall.arguments["openUrl"]));
        break;
    }
    return Future.value(true);
  }

  dispose() {
    _initCloudChannelResultController.close();
    _onMessageArrivedController.close();
    _onNotificationController.close();
    _onNotificationRemovedController.close();
    _onNotificationClickedWithNoActionController.close();
    _onNotificationReceivedInAppController.close();
  }
}
